// 声网工具类
import AgoraRTC from 'agora-rtc-sdk'

import {
  videoModes,
  agoraConfig
} from '@/setting/agora-config'

const deviceTypes = {
  'videoInput': 'videoinput',
  'audioInput': 'audioinput',
  'audioOutput': 'audiooutput'
}

/**
 * 声网客户端事件回调类型
 *    参考地址：https://docs.agora.io/cn/Video/API%20Reference/web/interfaces/agorartc.client.html#on
 * @type {{}}
 */
const clientEvents = {

  // 回调通知 App 本地音视频流已发布
  streamPublished: 'stream-published',

  // 回调通知 App 远程音视频流已添加
  streamAdded: 'stream-added',

  // 回调通知 App 已删除远程音视频流，即对方调用了 Client.unpublish
  streamRemoved: 'stream-removed',

  // 回调通知 App 已接收远程音视频流
  streamSubscribed: 'stream-subscribed',

  // 回调通知 App 对方用户已离开频道，即对方调用了 Client.leave
  peerLeave: 'peer-leave',

  // 回调通知 App 对方用户在语音通话中将自己的声音关掉
  muteAudio: 'mute-audio',

  // 该回调通知 App 对方用户在语音通话中将自己的声音打开
  unmuteAudio: 'unmute-audio',

  // 回调通知 App 对方用户在视频通话中将自己的视频关掉
  muteVideo: 'mute-video',

  // 回调通知 App 对方用户在视频通话中将自己的视频打开
  unmuteVideo: 'unmute-video',

  // 回调通知用户已经在聊天过程中被踢，或没有进入频道就被封禁。当前只有被踢的用户会收到这个回调
  clientBanned: 'client-banned',

  // 回调通知 App 频道内谁在说话（音量最大的用户）
  activeSpeaker: 'active-speaker',

  // 回调提示频道内正在说话的远端用户及其音量
  volumeIndicator: 'volume-indicator',

  // 回调通知 App 直播推流成功
  liveStreamingStarted: 'liveStreamingStarted',

  // 回调通知 App 直播推流失败
  liveStreamingFailed: 'liveStreamingFailed',

  // 通知 App 直播推流已停止
  liveStreamingStopped: 'liveStreamingStopped',

  // 通知 App 主播转码已更新
  liveTranscodingUpdated: 'liveTranscodingUpdated',

  // 在 Token 过期前 30 秒，会收到该事件通知
  onTokenPrivilegeWillExpire: 'onTokenPrivilegeWillExpire',

  // 在 Token 过期后，会收到该事件通知
  onTokenPrivilegeDidExpire: 'onTokenPrivilegeDidExpire',

  // 回调通知 App 有出错信息，需要进行处理
  error: 'error',

  // 回调通知 App 有音频输入设备被添加或移除
  recordingDeviceChanged: 'recordingDeviceChanged',

  // 回调通知 App 有音频输出设备被添加或移除
  playoutDeviceChanged: 'playoutDeviceChanged',

  // 回调通知 App 有摄像头被添加或移除
  cameraChanged: 'cameraChanged',

  // 回调通知 App 视频流类型发生改变
  streamTypeChange: 'streamTypeChange'
}

// 初始化音视频对象，失败错误信息，{type: "error", msg: "MEDIA_OPTION_INVALID"}
const initStreamErrors = {
  MEDIA_OPTION_INVALID: {
    errorCode: 'MEDIA_OPTION_INVALID',
    errorMsg: '摄像头被占用或者分辨率不支持'
  },

  DEVICES_NOT_FOUND: {
    errorCode: 'DEVICES_NOT_FOUND',
    errorMsg: '没有找到设备'

  },

  NOT_SUPPORTED: {
    errorCode: 'NOT_SUPPORTED',
    errorMsg: '浏览器不支持获取获取摄像头和麦克风'

  },

  PERMISSION_DENIED: {
    errorCode: 'PERMISSION_DENIED',
    errorMsg: '浏览器禁用设备或者用户拒绝打开设备'

  },

  CONSTRAINT_NOT_SATISFIED: {
    errorCode: 'CONSTRAINT_NOT_SATISFIED',
    errorMsg: '配置参数不合法'

  },

  UNDEFINED: {
    errorCode: 'UNDEFINED',
    errorMsg: '未定义错误'
  }
}

/**
 * 判断系统是否支持声网环境
 *
 * @return  boolean  true | false
 */
function supportSystem () {
  return AgoraRTC.checkSystemRequirements()
}

/**
 * 获取视频设备
 * @return {Array}
 */
function getVideoDevices () {
  let vds = []
  AgoraRTC.getDevices(devices => {
    devices.forEach((device, i) => {
      let type = device.kind
      switch (type) {
        case deviceTypes.videoInput:
          vds.push(device)
          break
        default:
          break
      }
    })
  })
  return vds
}

/**
 * 获取音频（输入）设备
 * @return {Array}
 */
function getAudioDevices () {
  let ads = []
  AgoraRTC.getDevices(devices => {
    devices.forEach((device, i) => {
      let type = device.kind
      switch (type) {
        case deviceTypes.audioInput:
          ads.push(device)
          break
        default:
          break
      }
    })
  })
  return ads
}

/**
 * 判断系统是否支持  <b>纯视频</b> 模式
 * @return {boolean}
 */
function supportVideo () {
  return getVideoDevices().length > 0
}

/**
 * 判断系统是否支持 <b>纯音频</b> 模式
 * @return {boolean}
 */
function supportAudio () {
  return getAudioDevices().length > 0
}

/**
 * 判断双系统是否支持 <b>视频&&音频</b> 模式
 * @return {boolean}
 */
function supportVideoAndAudio () {
  return supportVideo() && supportAudio()
}

/**
 * 创建声网客户端
 * @param agoraSetting 初始化参数
 * @return Agora Client
 */
function createAgoraClient (agoraSetting) {
  if (agoraSetting) {
    return AgoraRTC.createClient(agoraSetting)
  } else {
    return AgoraRTC.createClient(agoraConfig)
  }
}

/**
 * 初始化视频流
 *
 * @param uid 用户
 * @param videoMode 视频模式
 * @param videoProfile 分辨率
 * @return stream 视频流
 */
function createStream (userId, videoMode, videoProfile) {
  let streamSpec = {
    streamID: userId,
    audio: true,
    video: true,
    screen: false
  }

  switch (videoMode) {
    case videoModes.audience: {
      streamSpec.audio = false
      streamSpec.video = false
      break
    }
    case videoModes.audio: {
      streamSpec.video = false
      break
    }
    case videoModes.video: {
      break
    }
    default: {
      // nothing to do
      break
    }
  }

  let stream = AgoraRTC.createStream(streamSpec)
  stream.setVideoProfile(videoProfile)

  return stream
}

export {
  deviceTypes,
  clientEvents,
  initStreamErrors,
  supportSystem,
  getVideoDevices,
  getAudioDevices,
  supportVideo,
  supportAudio,
  supportVideoAndAudio,
  createAgoraClient,
  createStream

}
